﻿using HCMS.IServices.OAuth2;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;

namespace HCMS.HttpApi.Site.Filter
{
    /// <summary>
    /// 方法 授权校验 过滤器
    /// </summary>
    public class ActionAuthFilter : Attribute, IAsyncActionFilter
    {
        private readonly IOAuth2AccessTokenAppService oauth2AccessTokenAppService;

        public ActionAuthFilter(IOAuth2AccessTokenAppService oauth2AccessTokenAppService)
        {
            this.oauth2AccessTokenAppService = oauth2AccessTokenAppService;
        }

        /// <summary>
        /// 方法 执行时 调用
        /// </summary>
        /// <param name="context"></param>
        /// <param name="next"></param>
        /// <returns></returns>
        public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
        {
            var endpointMetadata = context.ActionDescriptor.EndpointMetadata;

            // 允许匿名访问
            bool hasAllowAnonymous = endpointMetadata.Any(em => em.GetType() == typeof(AllowAnonymousAttribute));
            if (hasAllowAnonymous)
            {
                await next();
                return;
            }

            // ?AppId=1&Secret=2
            var queryString = context.HttpContext.Request.QueryString;
            if (!queryString.HasValue)
            {
                // 没有有效的查询参数
                context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
                return;
            }
            if (!queryString.Value.Contains("access_token"))
            {
                // 没有有效的 access_token 参数
                context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
                return;
            }
            var accessToken = "";
            var queryArgsArray = queryString.Value.Replace("?", "").Split("&", StringSplitOptions.RemoveEmptyEntries);
            foreach (var queryArgs in queryArgsArray)
            {
                if (queryArgs.Contains("access_token"))
                {
                    var tokenArgs = queryArgs.Split("=", StringSplitOptions.RemoveEmptyEntries);
                    accessToken = tokenArgs.Length == 2 ? tokenArgs[1] : "";
                    break;
                }
            }
            if (string.IsNullOrWhiteSpace(accessToken))
            {
                // 没有有效的 access_token 参数
                context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
                return;
            }

            var isValid = await oauth2AccessTokenAppService.TokenValidation(accessToken);
            if (!isValid)
            {
                // 无效 access_token 参数
                context.HttpContext.Response.StatusCode = StatusCodes.Status403Forbidden;
                return;
            }

            await next();
        }
    }
}
